# -*- coding: UTF-8 -*-
'''
@Project ：push_rk
@File ：app.py
@IDE ：PyCharm
@Author ：苦瓜
@Date ：2025/9/25 9:09
@Note: Something beautiful is about to happen !
'''
from flask import Flask, render_template, request
from keras.src.utils import load_img, img_to_array
from model import VGG16
import os

app = Flask(__name__)

model = VGG16()
model.build(input_shape=(None, 28, 28, 1))
model.load_weights('model.weights.h5')  # 加载模型权重

def read_image(path_):
    image = load_img(path_, color_mode='grayscale', target_size=(1, 28, 28, 1))
    image = img_to_array(image).reshape(1, 28, 28, 1) / 255.
    return image

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/predict', methods=['POST'])
def predict():
    try:
        if request.method == 'POST':
            input_file = request.files['file']  # 获取文件
            # 判断文件不存在
            if not input_file:
                return render_template('error.html', error='input_file 不存在')
            # 保存文件、构建保存路径
            path_ = f"static/images/{input_file.filename}"
            input_file.save(path_)
            # 判断文件大小
            if os.path.getsize(path_) > 1024 * 1024 * 5:
                os.remove(path_)
                return render_template('error.html', error='上传的文件过大！请重新上传')
                # 处理用户上传的图片
            image = read_image(path_)
            # 预测
            y_pred = model.predict(image).argmax()
            return render_template('predict.html', user_image=path_, product=y_pred)
        else:
            return render_template('predict.html')
    except Exception as e:
        return render_template('error.html', error=str(e))


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=6008, debug=True)

# 1)	图像上传与读取约束：
# 用户可以通过表单上传图像文件。
# 系统支持读取上传的图像文件，并将其转换为模型可处理的格式（28x28像素的灰度图像）。
# 2)	图像预处理约束：
# 上传的图像会被调整为28x28像素的大小，并转换为灰度图像。
# 图像数据会被归一化到0到1之间。
# 3)	模型加载与预测约束：
# 系统会加载一个名为mnist_vgg16的自定义VGG16模型，该模型已针对MNIST数据集进行训练。
# 使用加载的模型对预处理后的图像进行预测，并返回预测结果。
# 4)	用户交互约束：
# 用户可以通过Web界面上传图像并查看预测结果。
# 系统会向用户显示上传的图像和预测的类别。
# 5)	错误处理约束：
# 如果无法读取上传的文件，系统会向用户显示错误消息。
# 6)	服务器配置约束：
# Flask应用程序将在调试模式下运行，以便在开发过程中进行调试。
# 服务器将监听0.0.0.0地址上的6008端口，以便从任何网络接口进行访问。